#include "GUIPanel.h"

GUIPanel::GUIPanel()
{

	// The additional panels
	vector<GUIPanel_struct*> m_panels;
	vector<GUIPanel_text_struct*> m_texts;

	// Initializing some variables
	m_dimensions.w = 1;
	m_dimensions.h = 1;
	m_coordinates.x = 1;
	m_coordinates.y = 1;
	m_active = false;
	m_fade = 0.0f;

	// Reserve 5 buttons / texts / panels
	m_buttons.reserve(5);
	m_texts.reserve(5);
	m_panels.reserve(5);

	// The display color of the panel
	m_color.a = 0.0f;
	m_color.b = 0.0f;
	m_color.g = 0.0f;
	m_color.r = 0.0f;

}

GUIPanel::~GUIPanel()
{
}

// Sets the display color of the panel
void GUIPanel::SetColor(const OGL_Color& color)
{
	m_color.a = color.a;
	m_color.b = color.b;
	m_color.g = color.g;
	m_color.r = color.r;
}

// Draw opaque object
void GUIPanel::DrawOpaq()
{
	// Only draw if the GUIPanel is active
	if(m_active)
	{
		// Only display if 66% of panel is done fading in
		if(m_fadeInOut)
			if(m_fade < m_color.a / 1.5f)
				return;

		// Iterate through buttons, display their surface, and display their text (force the iter to go out of scope)
		{
			vector<Button>::iterator iter;
			for(iter = m_buttons.begin(); iter != m_buttons.end(); ++iter)
			{
				iter->applySurface();
				Key->GetFont("onuava")->drawText(iter->GetMidX(FONT_SIZE_SMALL), iter->GetMidY(FONT_SIZE_SMALL), iter->GetText(), red);
				//TextDisplay->DisplayMessage(iter->GetText(), red, iter->GetMidX(FONT_SIZE_SMALL), iter->GetMidY(FONT_SIZE_SMALL), (FONT_SIZE_SMALL));
			}
		}

		// Draw the "additional" text using an... iterator
		vector<GUIPanel_text_struct>::const_iterator iter;
		for(iter = m_texts.begin(); iter != m_texts.end(); ++iter)
			Key->GetFont(iter->font_name)->drawText(iter->x, iter->y, iter->text, iter->color);
			//TextDisplay->DisplayMessage(iter->text, Key->GetFont(iter->font_name), iter->color, iter->x, iter->y, iter->font_size);
	}
}

bool GUIPanel::DrawExternalTextures()
{
	// Return true if active
	if(m_active)
	{
		// If we are fading and we have not faded in enough then return false
		if(m_fadeInOut)
			if(m_fade < m_color.a / 1.5f)
				return false;

		return true;
	}

	// Return false if not active
	return false;
}

// Draw transparent objects
void GUIPanel::DrawTrans()
{
	// Only draw if the GUIPanel is active
	if(m_active)
	{

		// If we are fading in
		if(m_fadeInOut)
		{
			DrawPrimitives->DrawRectangle(m_coordinates.x, m_coordinates.y, m_coordinates.x + m_dimensions.w, m_coordinates.y + m_dimensions.h, m_color, m_fade);

			// Draw the "additional" panels using an... iterator
			vector<GUIPanel_struct>::const_iterator iter;
			for(iter = m_panels.begin(); iter != m_panels.end(); ++iter)
			{
				DrawPrimitives->DrawRectangle(iter->x, iter->y, iter->x + iter->w, iter->y + iter->h, iter->color, m_fade);
			}

			// Increase / decrease fading level
			m_fade += m_fadeIncementLevel * (m_timer.GetElapsedSeconds() );

			// Stop fading if the fade level is above the normal alpha
			if((m_fade > m_color.a))
			{
				m_fadeInOut = false;
				m_fade = m_color.a;
			}

			// Stop fading if the fade level is below zero and turn the panel off
			else if(m_fade < 0.0f)
			{
				m_fadeInOut = false;
				m_active = false;
				m_fade = 0.0f;
			}
		}

		// We are not fading in
		else
		{
			DrawPrimitives->DrawRectangle(m_coordinates.x, m_coordinates.y, m_coordinates.x + m_dimensions.w, m_coordinates.y + m_dimensions.h, m_color);
			
			// Draw the "additional" panels using an... iterator
			vector<GUIPanel_struct>::const_iterator iter;
			for(iter = m_panels.begin(); iter != m_panels.end(); ++iter)
				DrawPrimitives->DrawRectangle(iter->x, iter->y, iter->x + iter->w, iter->y + iter->h, iter->color);
		}

		// Restart the timer
		m_timer.Restart();

	}
}

// Check to see if the mouse is over the button...
void GUIPanel::HandleGraphicalEvents()
{

	int xPos;
	int yPos;
	SDL_GetMouseState(&xPos, &yPos);
	Coords m_mouse(xPos, yPos);

	// Iterate through buttons
	for(unsigned int i = 0; i < m_buttons.size(); ++i)
		//if(m_buttons[i].inBounds(m_mouse.x, m_mouse.y))
		//	m_buttons[i].SetMouseOverGraphic();
		//else
		//	m_buttons[i].SetNameGraphic();
		m_buttons[i].inBounds(m_mouse.x, m_mouse.y);
}

// Returns the bounds of a specified button
bool GUIPanel::GetBounds(int button)
{
	// If the button doesn't exit return false
	if((unsigned int)button <= m_buttons.size() || button > 0)
		return false;

	int xPos;
	int yPos;

	SDL_GetMouseState(&xPos, &yPos);
	Coords m_mouse(xPos, yPos);
	return  m_buttons[button].inBounds(m_mouse.x, m_mouse.y);

}

// Add a button to the GUI panel
void GUIPanel::AddButton(const Coords& coordinates, const Dimension& dimensions, string buttonText, string imgID, string mouseover_imgID)
{
	// Make the vector bigger
	m_buttons.resize(m_buttons.size() + 1);

	// Change the button's coordinates
	m_buttons[m_buttons.size() - 1].SetXY(coordinates.x, coordinates.y, coordinates.x + dimensions.w, coordinates.y + dimensions.h);

	// Set the button's text
	m_buttons[m_buttons.size() - 1].SetText(buttonText);

	// Change the buttons images
	m_buttons[m_buttons.size() - 1].SetImages(imgID, mouseover_imgID);


}

// Updates the buttons / things with textures in the GUIPanel
void GUIPanel::Update()
{
	for(unsigned int i = 0; i < m_buttons.size(); ++i)
		m_buttons[i].Update();

}

bool GUIPanel::GetPanelBounds(const int& x, const int& y)
{
	// Is the mouse in the bounds of the panel and is this panel active?
	if((x >= m_coordinates.x) && (x <= m_coordinates.x + m_dimensions.w) && 
		(y >= m_coordinates.y) && (y <= m_coordinates.y + m_dimensions.h) && 
		(m_active == true))
		return true;


	// Not in bounds, return false
    return false;
}

// Adds an additional panel to the GUIPanel
void GUIPanel::AddPanel(int x, int y, int w, int h, const OGL_Color& color)
{
	// I could have just used the resize function, but I like this better.  Probably better practice.
	GUIPanel_struct panel;
	panel.x = x;
	panel.y = y;
	panel.w = w;
	panel.h = h;
	panel.color = color;

	m_panels.push_back(panel);

}

// Adds additional text to the GUIPanel
void GUIPanel::AddText(int x, int y, const char* text, const OGL_Color& color, const char* font_name)
{
	// I could have just used the resize function, but I like this better.  Probably better practice.
	GUIPanel_text_struct _text;
	_text.text = (char*)text;		// No one likes you.
	_text.x = x;
	_text.y = y;
	_text.color = color;
	_text.font_name = (char*)font_name;

	m_texts.push_back(_text);

}

void GUIPanel::ClearText()
{
	m_texts.clear();
}